Prepare county level data
Overview of time windows
US prevalence: 03/09 - 04/18 US socdist: 03/01 - 05/03
UK prevalence: 03/09 - 04/10 UK socdist: 03/01 - 03/31
GER prevalence: 01/01 - 04/25 GER socdist: 02/25 - 04/27
Conty level controls
df_us_ctrl <- read.csv('controls_US.csv')
df_us_ctrl <- df_us_ctrl %>% select(-county_name) %>%
rename(county_fips = county)
df_us_ctrl %>% head()
NA
Social distancing data unacast
df_us_socdist <- read_csv('0409_sds-full-county.csv')
# create sequence of dates
date_sequence <- seq.Date(as.Date('2020-03-09'),
as.Date('2020-03-31'), 1)
# create data frame with time sequence
df_dates = tibble(date_sequence, 1:length(date_sequence))
names(df_dates) <- c('date', 'time')
# merge day index with gps data
df_us_socdist = df_us_socdist %>%
merge(df_dates, by='date') %>%
arrange(county_fips) %>%
as_tibble()
df_us_socdist %>% head()
Social distancing data FB
fb_files <- list.files('../FB Data/US individual files/Mobility/',
'*.csv', full.names = T)
df_us_socdist_fb <- fb_files %>%
map(read_csv) %>% bind_rows()
df_us_socdist_fb$ds %>% summary()
Min. 1st Qu. Median Mean 3rd Qu. Max.
"2020-03-01" "2020-03-16" "2020-04-01" "2020-04-01" "2020-04-17" "2020-05-03"
df_us_socdist_fb <- df_us_socdist_fb %>%
select(-age_bracket, -gender, -baseline_name, -baseline_type) %>%
rename(date = ds,
county_fips = polygon_id,
county_name = polygon_name,
socdist_tiles = all_day_bing_tiles_visited_relative_change,
socdist_single_tile = all_day_ratio_single_tile_users)
df_us_socdist_fb <- df_us_socdist_fb %>%
filter(date >= '2020-03-09' & date <= '2020-03-31') %>%
group_by(county_fips) %>%
arrange(date) %>%
mutate(time = row_number()) %>%
ungroup() %>%
arrange(county_fips)
head(df_us_socdist_fb)
Sanity check socdist data
socdist <- df_us_socdist %>% merge(df_us_socdist_fb, by = c("county_fips", "time"))
socdist[c('daily_distance_diff', 'daily_visitation_diff', 'socdist_tiles', 'socdist_single_tile')] %>%
cor(use = 'pairwise.complete')
daily_distance_diff daily_visitation_diff socdist_tiles socdist_single_tile
daily_distance_diff 1.0000000 0.1361318 0.3061683 -0.2746350
daily_visitation_diff 0.1361318 1.0000000 0.3826102 -0.3624062
socdist_tiles 0.3061683 0.3826102 1.0000000 -0.7544123
socdist_single_tile -0.2746350 -0.3624062 -0.7544123 1.0000000
Merge data
df_us <- plyr::join_all(list(df_us_covid, df_us_socdist_fb),
by = c('county_fips', 'time'),
type = 'inner') %>%
plyr::join(df_us_ctrl, by='county_fips') %>%
arrange(county_fips, time)
# keep only counties with full data
fips_complete <- df_us %>%
group_by(county_fips) %>%
summarize(n = n()) %>%
filter(n==max(.$n)) %>%
.$county_fips
df_us <- df_us %>% filter(county_fips %in% fips_complete)
Explore data
Plot distributions
# distribution of observations per county
df_us %>% group_by(county_fips) %>%
summarise(mark = mean(mark)) %>%
ggplot(aes(x=mark)) +
geom_histogram(color="black", fill="white", binwidth = 300) +
ggtitle('Distribution of observations per county')

# distributions of mean prevalence rates per county
df_us %>% group_by(county_fips) %>%
summarise(rate_day = mean(rate_day)) %>%
ggplot(aes(x=rate_day)) +
geom_histogram(color="black", fill="white", binwidth = 0.01) +
ggtitle('Distribution of mean prevalence rates by county')

# distribution of mean sd distance measue
df_us %>% group_by(county_fips) %>%
summarise(socdist_tiles = mean(socdist_tiles)) %>%
ggplot(aes(x=socdist_tiles)) +
geom_histogram(color="black", fill="white", bins = 200) +
ggtitle('Distribution of mean tiles visited measure by county')

# distribution of mean sd visit measue
df_us %>% group_by(county_fips) %>%
summarise(socdist_single_tile = mean(socdist_single_tile)) %>%
ggplot(aes(x=socdist_single_tile)) +
geom_histogram(color="black", fill="white", bins = 200) +
ggtitle('Distribution of mean single tile measute by county')

NA
NA
Plot prevalence over time
df_us %>% sample_n(20000) %>%
ggplot(aes(x=time, y=rate_day)) +
geom_point(aes(col=county_name, size=mark)) +
geom_smooth(method="loess", se=T) +
theme(legend.position="none") +
ggtitle("Overall prevalence over time")
pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')
for (i in pers){
gg <- df_us %>% mutate(prev_tail = cut(.[[i]],
breaks = c(-Inf, quantile(.[[i]], 0.05), quantile(.[[i]], 0.95), Inf),
labels = c('lower tail', 'center', 'upper tail'))) %>%
filter(prev_tail != 'center') %>%
ggplot(aes(x=time, y=rate_day)) +
geom_point(aes(col=county_name, size=mark)) +
geom_smooth(method="loess", se=T) +
facet_wrap(~prev_tail) +
theme(legend.position="none") +
ggtitle(i)
print(gg)
}
Plot social distancing single tile visited
df_us %>% sample_n(10000) %>%
ggplot(aes(x=time, y=socdist_single_tile)) +
geom_point(aes(col=county_name, size=mark)) +
geom_smooth(method="loess", se=T) +
theme(legend.position="none") +
ggtitle("Overall social distancing (single tile) over time")

pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')
for (i in pers){
gg <- df_us %>% mutate(dist_tail = cut(.[[i]],
breaks = c(-Inf, quantile(.[[i]], 0.05), quantile(.[[i]], 0.95), Inf),
labels = c('lower tail', 'center', 'upper tail'))) %>%
filter(dist_tail != 'center') %>%
ggplot(aes(x=time, y=socdist_single_tile)) +
geom_point(aes(col=county_name, size=mark)) +
geom_smooth(method="loess", se=T) +
facet_wrap(~dist_tail) +
theme(legend.position="none") +
ggtitle(i)
print(gg)
}





Control for weekend effect
df_us %>% sample_n(10000) %>%
ggplot(aes(x=time, y=socdist_single_tile_clean)) +
geom_point(aes(col=county_name, size=mark)) +
geom_smooth(method="loess", se=T) +
theme(legend.position="none") +
ggtitle("Overall social distancing (single tile) over time")

pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')
for (i in pers){
gg <- df_us %>% mutate(dist_tail = cut(.[[i]],
breaks = c(-Inf, quantile(.[[i]], 0.05), quantile(.[[i]], 0.95), Inf),
labels = c('lower tail', 'center', 'upper tail'))) %>%
filter(dist_tail != 'center') %>%
ggplot(aes(x=time, y=socdist_single_tile_clean)) +
geom_point(aes(col=county_name, size=mark)) +
geom_smooth(method="loess", se=T) +
facet_wrap(~dist_tail) +
theme(legend.position="none") +
ggtitle(i)
print(gg)
}





Variance over time

Correlations
df_us %>% select(-time, -date, -county_name) %>%
group_by(county_fips) %>%
summarize_if(is.numeric, mean) %>%
select(-county_fips) %>%
cor(use='pairwise.complete.obs') %>%
round(3)
mark rate_day pers_o pers_c pers_e pers_a pers_n socdist_tiles socdist_single_tile
mark 1.000 0.189 0.279 -0.052 0.097 -0.041 -0.174 -0.377 0.214
rate_day 0.189 1.000 0.196 -0.049 0.044 -0.037 -0.094 -0.240 0.167
pers_o 0.279 0.196 1.000 -0.052 -0.086 -0.154 -0.228 -0.249 0.208
pers_c -0.052 -0.049 -0.052 1.000 0.148 0.650 -0.402 0.165 -0.258
pers_e 0.097 0.044 -0.086 0.148 1.000 0.235 -0.386 -0.065 -0.061
pers_a -0.041 -0.037 -0.154 0.650 0.235 1.000 -0.384 0.123 -0.277
pers_n -0.174 -0.094 -0.228 -0.402 -0.386 -0.384 1.000 0.062 0.190
socdist_tiles -0.377 -0.240 -0.249 0.165 -0.065 0.123 0.062 1.000 -0.595
socdist_single_tile 0.214 0.167 0.208 -0.258 -0.061 -0.277 0.190 -0.595 1.000
airport_distance -0.212 -0.055 -0.093 -0.094 -0.109 -0.103 0.040 0.258 -0.135
republican -0.345 -0.234 -0.349 -0.046 -0.077 -0.086 0.307 0.350 -0.231
medage -0.223 -0.075 -0.034 -0.066 -0.092 -0.074 0.232 0.013 0.301
male -0.115 -0.052 -0.117 -0.096 -0.058 -0.154 0.054 0.126 -0.041
popdens 0.322 0.375 0.222 -0.044 0.028 -0.070 -0.044 -0.244 0.221
manufact -0.162 -0.138 -0.386 0.070 0.034 0.119 0.179 0.057 -0.126
tourism 0.112 0.111 0.368 0.017 -0.003 -0.067 -0.188 -0.006 0.074
academics 0.418 0.284 0.462 -0.116 0.141 -0.145 -0.341 -0.434 0.259
medinc 0.307 0.228 0.226 -0.173 0.134 -0.219 -0.215 -0.444 0.225
physician_pc -0.181 -0.100 -0.213 0.107 -0.047 0.112 0.117 0.163 -0.114
airport_distance republican medage male popdens manufact tourism academics medinc
mark -0.212 -0.345 -0.223 -0.115 0.322 -0.162 0.112 0.418 0.307
rate_day -0.055 -0.234 -0.075 -0.052 0.375 -0.138 0.111 0.284 0.228
pers_o -0.093 -0.349 -0.034 -0.117 0.222 -0.386 0.368 0.462 0.226
pers_c -0.094 -0.046 -0.066 -0.096 -0.044 0.070 0.017 -0.116 -0.173
pers_e -0.109 -0.077 -0.092 -0.058 0.028 0.034 -0.003 0.141 0.134
pers_a -0.103 -0.086 -0.074 -0.154 -0.070 0.119 -0.067 -0.145 -0.219
pers_n 0.040 0.307 0.232 0.054 -0.044 0.179 -0.188 -0.341 -0.215
socdist_tiles 0.258 0.350 0.013 0.126 -0.244 0.057 -0.006 -0.434 -0.444
socdist_single_tile -0.135 -0.231 0.301 -0.041 0.221 -0.126 0.074 0.259 0.225
airport_distance 1.000 0.121 0.029 0.194 -0.144 -0.138 0.101 -0.133 -0.177
republican 0.121 1.000 0.134 0.162 -0.264 0.172 -0.220 -0.452 -0.192
medage 0.029 0.134 1.000 -0.040 -0.105 0.091 -0.080 -0.210 -0.107
male 0.194 0.162 -0.040 1.000 -0.101 -0.080 -0.046 -0.175 -0.004
popdens -0.144 -0.264 -0.105 -0.101 1.000 -0.120 0.049 0.242 0.154
manufact -0.138 0.172 0.091 -0.080 -0.120 1.000 -0.380 -0.385 -0.179
tourism 0.101 -0.220 -0.080 -0.046 0.049 -0.380 1.000 0.279 -0.022
academics -0.133 -0.452 -0.210 -0.175 0.242 -0.385 0.279 1.000 0.719
medinc -0.177 -0.192 -0.107 -0.004 0.154 -0.179 -0.022 0.719 1.000
physician_pc -0.038 0.196 0.078 0.159 -0.079 0.157 -0.226 -0.369 -0.202
physician_pc
mark -0.181
rate_day -0.100
pers_o -0.213
pers_c 0.107
pers_e -0.047
pers_a 0.112
pers_n 0.117
socdist_tiles 0.163
socdist_single_tile -0.114
airport_distance -0.038
republican 0.196
medage 0.078
male 0.159
popdens -0.079
manufact 0.157
tourism -0.226
academics -0.369
medinc -0.202
physician_pc 1.000
Model building
Prepare functions
# function calculates all relevant models
run_models <- function(y, lvl1_x, lvl2_x, lvl2_id, data, ctrls=F){
# subset data
data = data %>%
dplyr::select(all_of(y), all_of(lvl1_x), all_of(lvl2_x), all_of(lvl2_id),
popdens, rate_day, all_of(y))
data = data %>%
dplyr::rename(y = all_of(y),
lvl1_x = all_of(lvl1_x),
lvl2_x = all_of(lvl2_x),
lvl2_id = all_of(lvl2_id)
)
# configure optimization procedure
ctrl_config <- lmeControl(opt = 'optim', maxIter = 100, msMaxIter = 100)
# baseline
baseline <- lme(fixed = y ~ 1, random = ~ 1 | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# random intercept fixed slope
random_intercept <- lme(fixed = y ~ lvl1_x + lvl2_x,
random = ~ 1 | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# random intercept random slope
random_slope <- lme(fixed = y ~ lvl1_x + lvl2_x,
random = ~ lvl1_x | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# cross level interaction
interaction <- lme(fixed = y ~ lvl1_x * lvl2_x,
random = ~ lvl1_x | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# create list with results
results <- list('baseline' = baseline,
"random_intercept" = random_intercept,
"random_slope" = random_slope,
"interaction" = interaction)
if (ctrls == 'dem' | ctrls == 'prev'){
# random intercept random slope
random_slope_ctrl_dem <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens,
random = ~ lvl1_x | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# cross level interaction
interaction_ctrl_main_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens,
random = ~ lvl1_x | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# cross level interaction
interaction_ctrl_int_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens,
random = ~ lvl1_x | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# create list with results
results <- list('baseline' = baseline,
"random_intercept" = random_intercept,
"random_slope" = random_slope,
"interaction" = interaction,
"random_slope_ctrl_dem" = random_slope_ctrl_dem,
"interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
"interaction_ctrl_int_dem" = interaction_ctrl_int_dem)
}
if (ctrls == 'prev'){
# random intercept random slope
random_slope_ctrl_prev <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens + rate_day,
random = ~ lvl1_x + rate_day | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# cross level interaction
interaction_ctrl_main_prev <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens + rate_day,
random = ~ lvl1_x | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# cross level interaction
interaction_ctrl_int_prev<- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens + rate_day,
random = ~ lvl1_x + rate_day | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# create list with results
results <- list('baseline' = baseline,
"random_intercept" = random_intercept,
"random_slope" = random_slope,
"interaction" = interaction,
"random_slope_ctrl_dem" = random_slope_ctrl_dem,
"interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
"interaction_ctrl_int_dem" = interaction_ctrl_int_dem,
"random_slope_ctrl_prev" = random_slope_ctrl_prev,
"interaction_ctrl_main_prev" = interaction_ctrl_main_prev,
"interaction_ctrl_int_prev" = interaction_ctrl_int_prev)
}
if(ctrls == 'exp'){
# random intercept random slope
random_slope_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) + lvl2_x,
random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# cross level interaction
interaction_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) * lvl2_x,
random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id,
data = data,
correlation = corAR1(),
control = ctrl_config,
method = 'ML')
# create list with results
results <- list('baseline' = baseline,
"random_intercept" = random_intercept,
"random_slope" = random_slope,
"interaction" = interaction,
"random_slope_exp" = random_slope_exp,
"interaction_exp" = interaction_exp)
}
return(results)
}
# extracts table with coefficients and tests statistics
extract_results <- function(models) {
models_summary <- models %>%
map(summary) %>%
map("tTable") %>%
map(as.data.frame) %>%
map(round, 10)
# %>% map(~ .[str_detect(rownames(.), 'Inter|lvl'),])
return(models_summary)
}
compare_models <- function(models) {
mdl_names <- models %>% names()
str = ''
for (i in mdl_names){
mdl_str <- paste('models$', i, sep = '')
if(i == 'baseline'){
str <- mdl_str
}else{
str <- paste(str, mdl_str, sep=', ')
}
}
anova_str <- paste0('anova(', str, ')')
mdl_comp <- eval(parse(text=anova_str))
rownames(mdl_comp) = mdl_names
return(mdl_comp)
}
Predict prevalence
prevalence ~ openness
models_o_covid <-run_models(y = 'rate_day',
lvl1_x = 'time',
lvl2_x = 'pers_o',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'dem')
extract_results(models_o_covid)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
compare_models(models_o_covid)
NA
prevalence ~ conscientiousness
models_c_covid <-run_models(y = 'rate_day',
lvl1_x = 'time',
lvl2_x = 'pers_c',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'dem')
extract_results(models_c_covid)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
compare_models(models_c_covid)
NA
NA
prevalence ~ agreeableness
models_a_covid <-run_models(y = 'rate_day',
lvl1_x = 'time',
lvl2_x = 'pers_a',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'dem')
extract_results(models_a_covid)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
compare_models(models_a_covid)
NA
NA
prevalence ~ neuroticism
models_n_covid <-run_models(y = 'rate_day',
lvl1_x = 'time',
lvl2_x = 'pers_n',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'dem')
extract_results(models_n_covid)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
compare_models(models_n_covid)
NA
NA
Predict social distancing
social distancing ~ openness
models_o_sd <-run_models(y = 'socdist_single_tile',
lvl1_x = 'time',
lvl2_x = 'pers_o',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'prev')
extract_results(models_o_sd)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
$random_slope_ctrl_prev
$interaction_ctrl_main_prev
$interaction_ctrl_int_prev
compare_models(models_o_sd)
NA
NA
social distancing ~ conscientiousness
models_c_sd <-run_models(y = 'socdist_single_tile',
lvl1_x = 'time',
lvl2_x = 'pers_c',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'prev')
extract_results(models_c_sd)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
$random_slope_ctrl_prev
$interaction_ctrl_main_prev
$interaction_ctrl_int_prev
compare_models(models_c_sd)
NA
NA
social distancing ~ agreeableness
models_a_sd <-run_models(y = 'socdist_single_tile',
lvl1_x = 'time',
lvl2_x = 'pers_a',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'prev')
extract_results(models_a_sd)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
$random_slope_ctrl_prev
$interaction_ctrl_main_prev
$interaction_ctrl_int_prev
compare_models(models_a_sd)
NA
NA
social distancing ~ neuroticism
models_n_sd <-run_models(y = 'socdist_single_tile',
lvl1_x = 'time',
lvl2_x = 'pers_n',
lvl2_id = 'county_fips',
data = df_us_scaled,
ctrls = 'prev')
extract_results(models_n_sd)
$baseline
$random_intercept
$random_slope
$interaction
$random_slope_ctrl_dem
$interaction_ctrl_main_dem
$interaction_ctrl_int_dem
$random_slope_ctrl_prev
$interaction_ctrl_main_prev
$interaction_ctrl_int_prev
compare_models(models_n_sd)
NA
Create overview table
Define function to create overview tables
summary_table <- function(models, dv_name, prev=F){
temp_df_ctrl_main <- NULL
temp_df_ctrl_int <- NULL
temp_df_ctrl_int_prev <- NULL
for (i in models){
results <- i %>% extract_results()
results_ctrl_main <- results$interaction_ctrl_main_dem['lvl1_x:lvl2_x',]
temp_df_ctrl_main <- temp_df_ctrl_main %>% rbind(results_ctrl_main)
results_ctrl_int <- results$interaction_ctrl_int_dem['lvl1_x:lvl2_x',]
temp_df_ctrl_int <- temp_df_ctrl_int %>% rbind(results_ctrl_int)
if(prev){
results_ctrl_int_prev <- results$interaction_ctrl_int_prev['lvl1_x:lvl2_x',]
temp_df_ctrl_int_prev <- temp_df_ctrl_int_prev %>% rbind(results_ctrl_int_prev)
}
}
names_ctrl_main <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens')
rownames(temp_df_ctrl_main) <- names_ctrl_main
names_ctrl_int <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time')
rownames(temp_df_ctrl_int) <- names_ctrl_int
if(prev){
names_ctrl_int_prev <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time_prev')
rownames(temp_df_ctrl_int_prev) <- names_ctrl_int_prev
sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int, temp_df_ctrl_int_prev) %>% round(4)
}else{
sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int) %>% round(4)
}
return(sum_tab)
}
Create overview tables
# prevalence
models_prev <- list(models_o_covid,
models_c_covid,
models_e_covid,
models_a_covid,
models_n_covid)
sum_tab_prev <- summary_table(models_prev, dv_name = 'prev')
write.table(sum_tab_prev, quote=F)
Value Std.Error DF t-value p-value
prev~o*time_crtl_popdens 0.0244 0.0027 53135 9.1918 0
prev~c*time_crtl_popdens -0.0061 0.0027 53135 -2.266 0.0235
prev~e*time_crtl_popdens 0.0055 0.0027 53135 2.0302 0.0423
prev~a*time_crtl_popdens -0.0042 0.0027 53135 -1.572 0.116
prev~n*time_crtl_popdens -0.0109 0.0027 53135 -4.0489 1e-04
prev~o*time_crtl_popdens*time 0.013 0.0025 53134 5.1452 0
prev~c*time_crtl_popdens*time -0.0037 0.0025 53134 -1.5004 0.1335
prev~e*time_crtl_popdens*time 0.004 0.0025 53134 1.6065 0.1082
prev~a*time_crtl_popdens*time -4e-04 0.0025 53134 -0.179 0.858
prev~n*time_crtl_popdens*time -0.0085 0.0025 53134 -3.4502 6e-04
# social distancing
models_socdist <- list(models_o_sd,
models_c_sd,
models_e_sd,
models_a_sd,
models_n_sd)
sum_tab_socdist <- summary_table(models_socdist, dv_name = 'socdist', prev=T)
write.table(sum_tab_socdist, quote=F)
Value Std.Error DF t-value p-value
socdist~o*time_crtl_popdens 0.012 7e-04 53135 18.0098 0
socdist~c*time_crtl_popdens -0.006 7e-04 53135 -8.6385 0
socdist~e*time_crtl_popdens 0.0025 7e-04 53135 3.5181 4e-04
socdist~a*time_crtl_popdens -0.0067 7e-04 53135 -9.7575 0
socdist~n*time_crtl_popdens -0.0033 7e-04 53135 -4.5664 0
socdist~o*time_crtl_popdens*time 0.0099 7e-04 53134 14.8225 0
socdist~c*time_crtl_popdens*time -0.0055 7e-04 53134 -8.2817 0
socdist~e*time_crtl_popdens*time 0.0021 7e-04 53134 3.2025 0.0014
socdist~a*time_crtl_popdens*time -0.006 7e-04 53134 -9.0111 0
socdist~n*time_crtl_popdens*time -0.0028 7e-04 53134 -4.0934 0
socdist~o*time_crtl_popdens*time_prev 0.0102 7e-04 53133 15.0292 0
socdist~c*time_crtl_popdens*time_prev -0.0054 7e-04 53133 -8.1668 0
socdist~e*time_crtl_popdens*time_prev 0.0022 7e-04 53133 3.2724 0.0011
socdist~a*time_crtl_popdens*time_prev -0.0059 7e-04 53133 -8.8441 0
socdist~n*time_crtl_popdens*time_prev -0.0031 7e-04 53133 -4.5123 0
Conditional random forest analysis
Explore distribution of slopes
df_us_slope_prev %>% ggplot(aes(slope_prev)) + geom_histogram(bins = 100)

df_us_slope_socdist %>% ggplot(aes(slope_socdist)) + geom_histogram(bins = 100)

CRF prevalence ~ openness
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_o_fit_prev <- cforest(slope_prev ~ pers_o + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_prev[-1],
controls = ctrls)
crf_o_varimp_prev <- varimp(crf_o_fit_prev, nperm = 1)
crf_o_varimp_cond_prev <- varimp(crf_o_fit_prev, conditional = T, nperm = 1)
crf_o_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_o_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ conscientiousness
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_c_fit_prev <- cforest(slope_prev ~ pers_c + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_prev[-1],
controls = ctrls)
crf_c_varimp_prev <- varimp(crf_c_fit_prev, nperm = 1)
crf_c_varimp_cond_prev <- varimp(crf_c_fit_prev, conditional = T, nperm = 1)
crf_c_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_c_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ agreeableness
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_a_fit_prev <- cforest(slope_prev ~ pers_a + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_prev[-1],
controls = ctrls)
crf_a_varimp_prev <- varimp(crf_a_fit_prev, nperm = 1)
crf_a_varimp_cond_prev <- varimp(crf_a_fit_prev, conditional = T, nperm = 1)
crf_a_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_a_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ neuroticism
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_n_fit_prev <- cforest(slope_prev ~ pers_n + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_prev[-1],
controls = ctrls)
crf_n_varimp_prev <- varimp(crf_n_fit_prev, nperm = 1)
crf_n_varimp_cond_prev <- varimp(crf_n_fit_prev, conditional = T, nperm = 1)
crf_n_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_n_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ openness
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_o_fit_socdist <- cforest(slope_socdist ~ pers_o + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_socdist[-1],
controls = ctrls)
crf_o_varimp_socdist <- varimp(crf_o_fit_socdist, nperm = 1)
crf_o_varimp_cond_socdist <- varimp(crf_o_fit_socdist, conditional = T, nperm = 1)
crf_o_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_o_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ conscientiousness
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_c_fit_socdist <- cforest(slope_socdist ~ pers_c + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_socdist[-1],
controls = ctrls)
crf_c_varimp_socdist <- varimp(crf_c_fit_socdist, nperm = 1)
crf_c_varimp_cond_socdist <- varimp(crf_c_fit_socdist, conditional = T, nperm = 1)
crf_c_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_c_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ agreeableness
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_a_fit_socdist <- cforest(slope_socdist ~ pers_a + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_socdist[-1],
controls = ctrls)
crf_a_varimp_socdist <- varimp(crf_a_fit_socdist, nperm = 1)
crf_a_varimp_cond_socdist <- varimp(crf_a_fit_socdist, conditional = T, nperm = 1)
crf_a_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_a_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ neuroticism
ctrls <- cforest_unbiased(ntree=500, mtry=5)
crf_n_fit_socdist <- cforest(slope_socdist ~ pers_n + airport_distance + republican +
medage + male + popdens + manufact +
tourism + academics + medinc + physician_pc,
df_us_slope_socdist[-1],
controls = ctrls)
crf_n_varimp_socdist <- varimp(crf_n_fit_socdist, nperm = 1)
crf_n_varimp_cond_socdist <- varimp(crf_n_fit_socdist, conditional = T, nperm = 1)
crf_n_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

crf_n_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
ggplot(aes(x=variable, y=.)) +
geom_bar(stat = 'identity') +
theme(axis.text.x = element_text(angle = 90))

Linear models predicting slopes from personality
lm_slope_prev_pers <- lm(slope_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n,
data = df_us_slope_prev)
lm_slope_prev_pers %>% summary()
Call:
lm(formula = slope_prev ~ pers_o + pers_c + pers_e + pers_a +
pers_n, data = df_us_slope_prev)
Residuals:
Min 1Q Median 3Q Max
-0.11019 -0.02930 -0.01466 0.00224 1.64943
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.027854 0.001886 14.769 < 2e-16 ***
pers_o 0.017433 0.002045 8.525 < 2e-16 ***
pers_c -0.006911 0.002553 -2.707 0.00683 **
pers_e 0.004472 0.002094 2.135 0.03282 *
pers_a 0.000545 0.002601 0.210 0.83404
pers_n -0.005611 0.002374 -2.363 0.01819 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.09289 on 2420 degrees of freedom
Multiple R-squared: 0.04663, Adjusted R-squared: 0.04466
F-statistic: 23.67 on 5 and 2420 DF, p-value: < 2.2e-16
lm_slope_socdist_pers <- lm(slope_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n,
data = df_us_slope_socdist)
lm_slope_socdist_pers %>% summary()
Call:
lm(formula = slope_socdist ~ pers_o + pers_c + pers_e + pers_a +
pers_n, data = df_us_slope_socdist)
Residuals:
Min 1Q Median 3Q Max
-0.28392 -0.02426 -0.00637 0.01813 1.65694
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.104604 0.001132 92.426 < 2e-16 ***
pers_o 0.008687 0.001227 7.079 1.89e-12 ***
pers_c -0.004476 0.001532 -2.922 0.003512 **
pers_e 0.003246 0.001257 2.583 0.009841 **
pers_a -0.003405 0.001561 -2.181 0.029245 *
pers_n -0.004956 0.001425 -3.479 0.000513 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.05574 on 2420 degrees of freedom
Multiple R-squared: 0.04961, Adjusted R-squared: 0.04764
F-statistic: 25.26 on 5 and 2420 DF, p-value: < 2.2e-16
Linear models predicting slopes with controls
lm_slope_prev_pers <- lm(slope_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n +
airport_distance + republican + medage + male + popdens +
manufact + tourism + academics + medinc + physician_pc,
data = df_us_slope_prev)
lm_slope_prev_pers %>% summary()
Call:
lm(formula = slope_prev ~ pers_o + pers_c + pers_e + pers_a +
pers_n + airport_distance + republican + medage + male +
popdens + manufact + tourism + academics + medinc + physician_pc,
data = df_us_slope_prev)
Residuals:
Min 1Q Median 3Q Max
-0.31430 -0.02291 -0.00994 0.00277 1.59045
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.790e-02 1.713e-03 16.285 < 2e-16 ***
pers_o 2.761e-03 2.187e-03 1.263 0.206874
pers_c -3.284e-03 2.360e-03 -1.391 0.164245
pers_e 1.138e-03 1.932e-03 0.589 0.555932
pers_a 5.501e-03 2.476e-03 2.221 0.026416 *
pers_n 2.122e-03 2.359e-03 0.900 0.368348
airport_distance 2.754e-03 1.865e-03 1.477 0.139782
republican -7.602e-03 2.085e-03 -3.646 0.000272 ***
medage -6.650e-05 1.807e-03 -0.037 0.970654
male -2.818e-05 1.876e-03 -0.015 0.988018
popdens 3.369e-02 1.832e-03 18.395 < 2e-16 ***
manufact -2.120e-03 2.059e-03 -1.030 0.303341
tourism 5.024e-03 2.081e-03 2.414 0.015849 *
academics 4.209e-03 3.415e-03 1.232 0.217913
medinc 1.237e-02 2.824e-03 4.379 1.24e-05 ***
physician_pc 6.768e-04 1.889e-03 0.358 0.720186
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.08439 on 2410 degrees of freedom
Multiple R-squared: 0.2164, Adjusted R-squared: 0.2115
F-statistic: 44.37 on 15 and 2410 DF, p-value: < 2.2e-16
lm_slope_socdist_pers <- lm(slope_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n +
airport_distance + republican + medage + male + popdens +
manufact + tourism + academics + medinc + physician_pc,
data = df_us_slope_socdist)
lm_slope_socdist_pers %>% summary()
Call:
lm(formula = slope_socdist ~ pers_o + pers_c + pers_e + pers_a +
pers_n + airport_distance + republican + medage + male +
popdens + manufact + tourism + academics + medinc + physician_pc,
data = df_us_slope_socdist)
Residuals:
Min 1Q Median 3Q Max
-0.26752 -0.01730 -0.00324 0.01248 1.63123
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.1046597 0.0010362 101.000 < 2e-16 ***
pers_o -0.0003449 0.0013227 -0.261 0.794320
pers_c -0.0010022 0.0014272 -0.702 0.482618
pers_e 0.0004776 0.0011681 0.409 0.682670
pers_a 0.0007837 0.0014976 0.523 0.600800
pers_n 0.0023991 0.0014266 1.682 0.092753 .
airport_distance -0.0037722 0.0011277 -3.345 0.000835 ***
republican -0.0109897 0.0012610 -8.715 < 2e-16 ***
medage 0.0058495 0.0010931 5.351 9.55e-08 ***
male 0.0053010 0.0011348 4.671 3.16e-06 ***
popdens 0.0055870 0.0011077 5.044 4.91e-07 ***
manufact 0.0023425 0.0012451 1.881 0.060040 .
tourism 0.0039623 0.0012585 3.148 0.001662 **
academics 0.0056901 0.0020653 2.755 0.005912 **
medinc 0.0131087 0.0017081 7.675 2.39e-14 ***
physician_pc -0.0029367 0.0011424 -2.570 0.010215 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.05104 on 2410 degrees of freedom
Multiple R-squared: 0.2067, Adjusted R-squared: 0.2017
F-statistic: 41.85 on 15 and 2410 DF, p-value: < 2.2e-16
gg <- gg + geom_map(data=us_map_shape, map=us_map_shape,
aes(x = x, y = y, map_id=fips),
color="black", fill="white", size=0.25)
Error: `map` must have the columns `x`, `y`, and `id`
df_us_covid %>% filter(county == 23013)
Change point analysis
library(changepoint)
Successfully loaded changepoint package version 2.2.2
NOTE: Predefined penalty values changed in version 2.2. Previous penalty values with a postfix 1 i.e. SIC1 are now without i.e. SIC and previous penalties without a postfix i.e. SIC are now with a postfix 0 i.e. SIC0. See NEWS and help files for further details.
Preparation
# keep only counties with full data
fips_complete <- df_us_scaled %>%
group_by(county_fips) %>%
summarize(n = n()) %>%
filter(n==max(.$n)) %>%
.$county_fips
Prevalence
# run changepoint analysis
df_us_prev_cpt_results <- df_us_scaled %>% select(county_fips, rate_day) %>%
filter(county_fips %in% fips_complete) %>%
split(.$county_fips) %>%
map(~ cpt.meanvar(as.vector(.$rate_day),
class=TRUE,
param.estimates=TRUE,
Q=1))
# calculate change point
df_us_prev_cpt_day <- df_us_prev_cpt_results %>%
map(cpts) %>%
unlist() %>%
as.data.frame() %>%
rename(cpt_day_prev = '.') %>%
rownames_to_column('county_fips')
# calculate mean differences
df_us_prev_cpt_mean_diff <- df_us_prev_cpt_results %>%
map(param.est) %>%
map(~ .$mean) %>%
map(~ .[2]-.[1]) %>%
unlist() %>%
as.data.frame() %>%
rename(mean_diff_prev = '.') %>%
rownames_to_column('county_fips')
# calculate varaince differences
df_us_prev_cpt_var_diff <- df_us_prev_cpt_results %>%
map(param.est) %>%
map(~ .$variance) %>%
map(~ .[2]-.[1]) %>%
unlist() %>%
as.data.frame() %>%
rename(var_diff_prev = '.') %>%
rownames_to_column('county_fips')
# merge new variables
df_us_cpt_prev <- df_us_scaled %>%
select(-time, -rate_day, -socdist_single_tile, -socdist_single_tile_clean) %>%
distinct() %>%
mutate(county_fips = as.character(county_fips)) %>%
left_join(df_us_prev_cpt_day, by='county_fips') %>%
left_join(df_us_prev_cpt_mean_diff, by='county_fips') %>%
left_join(df_us_prev_cpt_var_diff, by='county_fips')
df_us_cpt_prev %>% select(cpt_day_prev) %>% map(hist)
$cpt_day_prev
$breaks
[1] 2 4 6 8 10 12 14 16 18 20 22
$counts
[1] 10 32 148 4 189 674 9 7 10 78
$density
[1] 0.004306632 0.013781223 0.063738157 0.001722653 0.081395349 0.290267011 0.003875969 0.003014643
[9] 0.004306632 0.033591731
$mids
[1] 3 5 7 9 11 13 15 17 19 21
$xname
[1] ".x[[i]]"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% select(mean_diff_prev) %>% map(hist)
$mean_diff_prev
$breaks
[1] 0 2 4 6 8 10 12 14 16 18 20 22 24 26
$counts
[1] 1106 34 7 5 2 3 3 0 0 0 0 0 1
$density
[1] 0.4763135228 0.0146425495 0.0030146425 0.0021533161 0.0008613264 0.0012919897 0.0012919897
[8] 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0004306632
$mids
[1] 1 3 5 7 9 11 13 15 17 19 21 23 25
$xname
[1] ".x[[i]]"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% select(var_diff_prev) %>% map(hist)
$var_diff_prev
$breaks
[1] -20 0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300
$counts
[1] 59 1007 4 0 3 4 6 0 0 0 0 0 0 0 0 1
$density
[1] 2.721402e-03 4.644834e-02 1.845018e-04 0.000000e+00 1.383764e-04 1.845018e-04 2.767528e-04
[8] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
[15] 0.000000e+00 4.612546e-05
$mids
[1] -10 10 30 50 70 90 110 130 150 170 190 210 230 250 270 290
$xname
[1] ".x[[i]]"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% dim()
[1] 2397 19
df_us_cpt_prev %>% drop_na() %>% dim()
[1] 1080 19
for(i in head(df_us_prev_cpt_results,18)){
plot(i)
}

















NA

Socdist
# run changepoint analysis
df_us_socdist_cpt_results <- df_us_scaled %>% select(county_fips, socdist_single_tile_clean) %>%
filter(county_fips %in% fips_complete) %>%
split(.$county_fips) %>%
map(~ cpt.meanvar(as.vector(.$socdist_single_tile_clean),
#penalty = 'Asymptotic',
class=TRUE,
param.estimates=TRUE,
Q=1,
test.stat = 'Normal'))
# calculate change point
df_us_socdist_cpt_day <- df_us_socdist_cpt_results %>%
map(cpts) %>%
unlist() %>%
as.data.frame() %>%
rename(cpt_day_socdist = '.') %>%
rownames_to_column('county_fips')
# calculate mean differences
df_us_socdist_cpt_mean_diff <- df_us_socdist_cpt_results %>%
map(param.est) %>%
map(~ .$mean) %>%
map(~ .[2]-.[1]) %>%
unlist() %>%
as.data.frame() %>%
rename(mean_diff_socdist = '.') %>%
rownames_to_column('county_fips')
# calculate varaince differences
df_us_socdist_cpt_var_diff <- df_us_socdist_cpt_results %>%
map(param.est) %>%
map(~ .$variance) %>%
map(~ .[2]-.[1]) %>%
unlist() %>%
as.data.frame() %>%
rename(var_diff_socdist = '.') %>%
rownames_to_column('county_fips')
# merge new variables
df_us_cpt_prev_socdist <- df_us_cpt_prev %>%
left_join(df_us_socdist_cpt_day, by='county_fips') %>%
left_join(df_us_socdist_cpt_mean_diff, by='county_fips') %>%
left_join(df_us_socdist_cpt_var_diff, by='county_fips')
df_us_cpt_prev_socdist %>% select(cpt_day_socdist) %>% map(hist)
$cpt_day_socdist
$breaks
[1] 2 4 6 8 10 12 14 16 18 20 22
$counts
[1] 11 116 564 592 591 76 106 12 2 327
$density
[1] 0.0022945348 0.0241969128 0.1176470588 0.1234876929 0.1232790989 0.0158531498 0.0221109720
[8] 0.0025031289 0.0004171882 0.0682102628
$mids
[1] 3 5 7 9 11 13 15 17 19 21
$xname
[1] ".x[[i]]"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% select(mean_diff_socdist) %>% map(hist)
$mean_diff_socdist
$breaks
[1] -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
$counts
[1] 6 42 337 1043 667 236 53 8 3 1 1
$density
[1] 0.0050062578 0.0350438048 0.2811848144 0.8702544848 0.5565289946 0.1969128077 0.0442219441
[8] 0.0066750104 0.0025031289 0.0008343763 0.0008343763
$mids
[1] -0.25 0.25 0.75 1.25 1.75 2.25 2.75 3.25 3.75 4.25 4.75
$xname
[1] ".x[[i]]"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% select(var_diff_socdist) %>% map(hist)
$var_diff_socdist
$breaks
[1] -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8
$counts
[1] 2 4 10 24 77 171 757 762 163 52 14 22 10 1 2 1
$density
[1] 0.004826255 0.009652510 0.024131274 0.057915058 0.185810811 0.412644788 1.826737452 1.838803089
[9] 0.393339768 0.125482625 0.033783784 0.053088803 0.024131274 0.002413127 0.004826255 0.002413127
$mids
[1] -1.3 -1.1 -0.9 -0.7 -0.5 -0.3 -0.1 0.1 0.3 0.5 0.7 0.9 1.1 1.3 1.5 1.7
$xname
[1] ".x[[i]]"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% dim()
[1] 2397 22
df_us_cpt_prev_socdist %>% drop_na() %>% dim()
[1] 999 22
for(i in head(df_us_socdist_cpt_results,18)){
plot(i)
}

















NA

Predicting change points
Linear models predicting change points (no controls)
lm_cpt_socdist_pers %>% summary()
Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a +
pers_n, data = df_us_cpt_prev_socdist)
Residuals:
Min 1Q Median 3Q Max
-9.284 -3.119 -1.269 1.149 12.870
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 11.48853 0.09662 118.902 < 2e-16 ***
pers_o -0.26056 0.10496 -2.483 0.013112 *
pers_c 0.15915 0.13093 1.216 0.224291
pers_e -0.35704 0.10756 -3.319 0.000915 ***
pers_a 0.61317 0.13367 4.587 4.72e-06 ***
pers_n 0.14504 0.12217 1.187 0.235243
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 4.731 on 2391 degrees of freedom
Multiple R-squared: 0.02744, Adjusted R-squared: 0.02541
F-statistic: 13.49 on 5 and 2391 DF, p-value: 5.281e-13
Linear models predicting change points with controls
lm_cpt_socdist_pers %>% summary()
Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a +
pers_n + airport_distance + republican + medage + male +
popdens + manufact + tourism + academics + medinc + physician_pc,
data = df_us_cpt_prev_socdist)
Residuals:
Min 1Q Median 3Q Max
-9.784 -3.111 -1.220 1.563 12.148
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 11.476908 0.094787 121.080 < 2e-16 ***
pers_o 0.083785 0.121134 0.692 0.48921
pers_c -0.008695 0.130595 -0.067 0.94692
pers_e -0.256051 0.107138 -2.390 0.01693 *
pers_a 0.415986 0.137692 3.021 0.00255 **
pers_n -0.314164 0.131217 -2.394 0.01673 *
airport_distance 0.077067 0.102536 0.752 0.45236
republican 0.533550 0.115417 4.623 3.99e-06 ***
medage 0.156947 0.100341 1.564 0.11792
male 0.017010 0.104308 0.163 0.87047
popdens 0.158159 0.101480 1.559 0.11924
manufact 0.077820 0.114000 0.683 0.49490
tourism -0.280650 0.114817 -2.444 0.01458 *
academics 0.066161 0.189260 0.350 0.72669
medinc -0.873767 0.156588 -5.580 2.68e-08 ***
physician_pc 0.139214 0.104699 1.330 0.18376
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 4.636 on 2376 degrees of freedom
(5 observations deleted due to missingness)
Multiple R-squared: 0.07064, Adjusted R-squared: 0.06477
F-statistic: 12.04 on 15 and 2376 DF, p-value: < 2.2e-16
LS0tCnRpdGxlOiAiQ09WSUQtMTkgVVMiCmF1dGhvcjogIkhlaW5yaWNoIFBldGVycyIKZGF0ZTogIjQvMTUvMjAyMCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCiMgTUFDCiBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICcvVXNlcnMvaHAyNTAwL0dvb2dsZSBEcml2ZS9TVFVEWS9Db2x1bWJpYS9SZXNlYXJjaC9Db3JvbmEvRGF0YS9VUycpCgpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KG5sbWUpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGFydHkpCmxpYnJhcnkoZG9QYXJhbGxlbCkKCmBgYAoKCiMgUHJlcGFyZSBjb3VudHkgbGV2ZWwgZGF0YSAKCiMjIyBPdmVydmlldyBvZiB0aW1lIHdpbmRvd3MKVVMgcHJldmFsZW5jZTogMDMvMDkgLSAwNC8xOApVUyBzb2NkaXN0OiAwMy8wMSAtIDA1LzAzCgpVSyBwcmV2YWxlbmNlOiAwMy8wOSAtIDA0LzEwClVLIHNvY2Rpc3Q6IDAzLzAxIC0gMDMvMzEKCkdFUiBwcmV2YWxlbmNlOiAwMS8wMSAtIDA0LzI1CkdFUiBzb2NkaXN0OiAwMi8yNSAtIDA0LzI3CgojIyMgUmVhZCBhbmQgZm9ybWF0IHByZXZhbGVuY2UgZGF0YSAKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgpkZl91c19jb3ZpZCA8LSByZWFkX2NzdigndGltZXNlcmllc191c2FfY291bnR5X21hcmNoMV9hcHJpbF8wOS5jc3YnKQpkZl91c19jb3ZpZCR0aW1lICU+JSBtYXgoKQoKZGZfdXNfY292aWQgPC0gZGZfdXNfY292aWQgJT4lIAogIGZpbHRlcih0aW1lIDw9MzEpICU+JSAKICBhcnJhbmdlKGNvdW50eWZpcHMpICU+JQogIG11dGF0ZShzdGFiaWwgPSAtc3RhYmlsKSAlPiUKICBkcGx5cjo6cmVuYW1lKGNvdW50eV9maXBzID0gY291bnR5ZmlwcywKICAgICAgICAgcGVyc19vID0gb3BlbiwgCiAgICAgICAgIHBlcnNfYyA9IHNjaSwKICAgICAgICAgcGVyc19lID0gZXh0cmEsCiAgICAgICAgIHBlcnNfYSA9IGFncmVlLAogICAgICAgICBwZXJzX24gPSBzdGFiaWwpCgoKZGZfdXNfY292aWQgPC0gZGZfdXNfY292aWQgJT4lIAogIGRwbHlyOjpzZWxlY3QoY291bnR5X2ZpcHMsIHRpbWUsIG1hcmssIHJhdGVfZGF5LCBwZXJzX28sCiAgICAgICAgICAgICAgICBwZXJzX2MsIHBlcnNfZSwgcGVyc19hLCBwZXJzX24pCgoKZGZfdXNfY292aWQgJT4lIGhlYWQoKQpgYGAKCiMjIyBDb250eSBsZXZlbCBjb250cm9scyAKYGBge3J9CgpkZl91c19jdHJsIDwtIHJlYWQuY3N2KCdjb250cm9sc19VUy5jc3YnKQoKZGZfdXNfY3RybCA8LSBkZl91c19jdHJsICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKSAlPiUgCiAgcmVuYW1lKGNvdW50eV9maXBzID0gY291bnR5KQoKZGZfdXNfY3RybCAlPiUgaGVhZCgpCgpgYGAKCgojIyMgU29jaWFsIGRpc3RhbmNpbmcgZGF0YSB1bmFjYXN0CmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKZGZfdXNfc29jZGlzdCA8LSByZWFkX2NzdignMDQwOV9zZHMtZnVsbC1jb3VudHkuY3N2JykKCiMgY3JlYXRlIHNlcXVlbmNlIG9mIGRhdGVzCmRhdGVfc2VxdWVuY2UgPC0gc2VxLkRhdGUoYXMuRGF0ZSgnMjAyMC0wMy0wOScpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFzLkRhdGUoJzIwMjAtMDMtMzEnKSwgMSkKICAgICAgICAgICAgICAgICAgICAgCgojIGNyZWF0ZSBkYXRhIGZyYW1lIHdpdGggdGltZSBzZXF1ZW5jZQpkZl9kYXRlcyA9IHRpYmJsZShkYXRlX3NlcXVlbmNlLCAxOmxlbmd0aChkYXRlX3NlcXVlbmNlKSkgCm5hbWVzKGRmX2RhdGVzKSA8LSBjKCdkYXRlJywgJ3RpbWUnKQoKIyBtZXJnZSBkYXkgaW5kZXggd2l0aCBncHMgZGF0YQpkZl91c19zb2NkaXN0ID0gZGZfdXNfc29jZGlzdCAlPiUgCiAgbWVyZ2UoZGZfZGF0ZXMsIGJ5PSdkYXRlJykgJT4lIAogIGFycmFuZ2UoY291bnR5X2ZpcHMpICU+JQogIGFzX3RpYmJsZSgpCgpkZl91c19zb2NkaXN0ICU+JSBoZWFkKCkKYGBgCgoKIyMjIFNvY2lhbCBkaXN0YW5jaW5nIGRhdGEgRkIKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgpmYl9maWxlcyA8LSBsaXN0LmZpbGVzKCcuLi9GQiBEYXRhL1VTIGluZGl2aWR1YWwgZmlsZXMvTW9iaWxpdHkvJywKICAgICAgICAgICAgICAgICAgICAgICAnKi5jc3YnLCBmdWxsLm5hbWVzID0gVCkKCmRmX3VzX3NvY2Rpc3RfZmIgPC0gZmJfZmlsZXMgJT4lIAogIG1hcChyZWFkX2NzdikgJT4lIGJpbmRfcm93cygpCgpkZl91c19zb2NkaXN0X2ZiJGRzICU+JSBzdW1tYXJ5KCkKCmRmX3VzX3NvY2Rpc3RfZmIgPC0gZGZfdXNfc29jZGlzdF9mYiAlPiUKICBzZWxlY3QoLWFnZV9icmFja2V0LCAtZ2VuZGVyLCAtYmFzZWxpbmVfbmFtZSwgLWJhc2VsaW5lX3R5cGUpICU+JQogIHJlbmFtZShkYXRlID0gZHMsCiAgICAgICAgIGNvdW50eV9maXBzID0gcG9seWdvbl9pZCwKICAgICAgICAgY291bnR5X25hbWUgPSBwb2x5Z29uX25hbWUsCiAgICAgICAgIHNvY2Rpc3RfdGlsZXMgPSBhbGxfZGF5X2JpbmdfdGlsZXNfdmlzaXRlZF9yZWxhdGl2ZV9jaGFuZ2UsCiAgICAgICAgIHNvY2Rpc3Rfc2luZ2xlX3RpbGUgPSBhbGxfZGF5X3JhdGlvX3NpbmdsZV90aWxlX3VzZXJzKQoKZGZfdXNfc29jZGlzdF9mYiA8LSBkZl91c19zb2NkaXN0X2ZiICU+JQogIGZpbHRlcihkYXRlID49ICcyMDIwLTAzLTA5JyAmIGRhdGUgPD0gJzIwMjAtMDMtMzEnKSAlPiUKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIGFycmFuZ2UoZGF0ZSkgJT4lIAogIG11dGF0ZSh0aW1lID0gcm93X251bWJlcigpKSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGFycmFuZ2UoY291bnR5X2ZpcHMpCgpoZWFkKGRmX3VzX3NvY2Rpc3RfZmIpCmBgYAoKIyMjIFNhbml0eSBjaGVjayBzb2NkaXN0IGRhdGEKYGBge3J9CnNvY2Rpc3QgPC0gZGZfdXNfc29jZGlzdCAlPiUgbWVyZ2UoZGZfdXNfc29jZGlzdF9mYiwgYnkgPSBjKCJjb3VudHlfZmlwcyIsICJ0aW1lIikpIAoKc29jZGlzdFtjKCdkYWlseV9kaXN0YW5jZV9kaWZmJywgJ2RhaWx5X3Zpc2l0YXRpb25fZGlmZicsICdzb2NkaXN0X3RpbGVzJywgJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnKV0gJT4lIAogIGNvcih1c2UgPSAncGFpcndpc2UuY29tcGxldGUnKQoKYGBgCgoKIyMjIE1lcmdlIGRhdGEKYGBge3J9CgpkZl91cyA8LSBwbHlyOjpqb2luX2FsbChsaXN0KGRmX3VzX2NvdmlkLCBkZl91c19zb2NkaXN0X2ZiKSwKICAgICAgICAgICAgICAgICAgYnkgPSBjKCdjb3VudHlfZmlwcycsICd0aW1lJyksIAogICAgICAgICAgICAgICAgICB0eXBlID0gJ2lubmVyJykgJT4lIAogIHBseXI6OmpvaW4oZGZfdXNfY3RybCwgYnk9J2NvdW50eV9maXBzJykgJT4lIAogIGFycmFuZ2UoY291bnR5X2ZpcHMsIHRpbWUpCgojIGtlZXAgb25seSBjb3VudGllcyB3aXRoIGZ1bGwgZGF0YQpmaXBzX2NvbXBsZXRlIDwtIGRmX3VzICU+JSAKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIHN1bW1hcml6ZShuID0gbigpKSAlPiUgCiAgZmlsdGVyKG49PW1heCguJG4pKSAlPiUgCiAgLiRjb3VudHlfZmlwcwoKZGZfdXMgPC0gZGZfdXMgJT4lIGZpbHRlcihjb3VudHlfZmlwcyAlaW4lIGZpcHNfY29tcGxldGUpCgpgYGAKCiMjIEV4cGxvcmUgZGF0YQojIyMgUGxvdCBkaXN0cmlidXRpb25zCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQoKIyBkaXN0cmlidXRpb24gb2Ygb2JzZXJ2YXRpb25zIHBlciBjb3VudHkKZGZfdXMgJT4lIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXNlKG1hcmsgPSBtZWFuKG1hcmspKSAlPiUgCiAgZ2dwbG90KGFlcyh4PW1hcmspKSArIAogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJibGFjayIsIGZpbGw9IndoaXRlIiwgYmlud2lkdGggPSAzMDApICsKICBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2Ygb2JzZXJ2YXRpb25zIHBlciBjb3VudHknKQoKICAKIyBkaXN0cmlidXRpb25zIG9mIG1lYW4gcHJldmFsZW5jZSByYXRlcyBwZXIgY291bnR5CmRmX3VzICU+JSBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIHN1bW1hcmlzZShyYXRlX2RheSA9IG1lYW4ocmF0ZV9kYXkpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9cmF0ZV9kYXkpKSArIAogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJibGFjayIsIGZpbGw9IndoaXRlIiwgYmlud2lkdGggPSAwLjAxKSArCiAgZ2d0aXRsZSgnRGlzdHJpYnV0aW9uIG9mIG1lYW4gcHJldmFsZW5jZSByYXRlcyBieSBjb3VudHknKQoKICAKIyBkaXN0cmlidXRpb24gb2YgbWVhbiBzZCBkaXN0YW5jZSBtZWFzdWUKZGZfdXMgJT4lIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXNlKHNvY2Rpc3RfdGlsZXMgPSBtZWFuKHNvY2Rpc3RfdGlsZXMpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9c29jZGlzdF90aWxlcykpICsgCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsYWNrIiwgZmlsbD0id2hpdGUiLCBiaW5zID0gMjAwKSArCiBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2YgbWVhbiB0aWxlcyB2aXNpdGVkIG1lYXN1cmUgYnkgY291bnR5JykKCgojIGRpc3RyaWJ1dGlvbiBvZiBtZWFuIHNkIHZpc2l0IG1lYXN1ZQpkZl91cyAlPiUgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JSAKICBzdW1tYXJpc2Uoc29jZGlzdF9zaW5nbGVfdGlsZSA9IG1lYW4oc29jZGlzdF9zaW5nbGVfdGlsZSkpICU+JQogIGdncGxvdChhZXMoeD1zb2NkaXN0X3NpbmdsZV90aWxlKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIsIGJpbnMgPSAyMDApICsKICBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2YgbWVhbiBzaW5nbGUgdGlsZSBtZWFzdXRlIGJ5IGNvdW50eScpCgoKYGBgCgojIyMgUGxvdCBwcmV2YWxlbmNlIG92ZXIgdGltZQpgYGB7cn0KCmRmX3VzICU+JSBzYW1wbGVfbigyMDAwMCkgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9cmF0ZV9kYXkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1tYXJrKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZSgiT3ZlcmFsbCBwcmV2YWxlbmNlIG92ZXIgdGltZSIpCgoKCnBlcnMgPC0gYygncGVyc19vJywgJ3BlcnNfYycsICdwZXJzX2UnLCAncGVyc19hJywgJ3BlcnNfbicpCgpmb3IgKGkgaW4gcGVycyl7CgpnZyA8LSBkZl91cyAlPiUgbXV0YXRlKHByZXZfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4wNSksIHF1YW50aWxlKC5bW2ldXSwgMC45NSksIEluZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoJ2xvd2VyIHRhaWwnLCAnY2VudGVyJywgJ3VwcGVyIHRhaWwnKSkpICU+JSAKICBmaWx0ZXIocHJldl90YWlsICE9ICdjZW50ZXInKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dGltZSwgeT1yYXRlX2RheSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPW1hcmspKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIGZhY2V0X3dyYXAofnByZXZfdGFpbCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZShpKQoKcHJpbnQoZ2cpCn0KCmBgYAoKIyMjIFBsb3Qgc29jaWFsIGRpc3RhbmNpbmcgc2luZ2xlIHRpbGUgdmlzaXRlZApgYGB7cn0KCmRmX3VzICU+JSBzYW1wbGVfbigxMDAwMCkgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPW1hcmspKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJPdmVyYWxsIHNvY2lhbCBkaXN0YW5jaW5nIChzaW5nbGUgdGlsZSkgb3ZlciB0aW1lIikKCnBlcnMgPC0gYygncGVyc19vJywgJ3BlcnNfYycsICdwZXJzX2UnLCAncGVyc19hJywgJ3BlcnNfbicpCgpmb3IgKGkgaW4gcGVycyl7CgpnZyA8LSBkZl91cyAlPiUgbXV0YXRlKGRpc3RfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4wNSksIHF1YW50aWxlKC5bW2ldXSwgMC45NSksIEluZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoJ2xvd2VyIHRhaWwnLCAnY2VudGVyJywgJ3VwcGVyIHRhaWwnKSkpICU+JSAKICBmaWx0ZXIoZGlzdF90YWlsICE9ICdjZW50ZXInKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3NpbmdsZV90aWxlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2w9Y291bnR5X25hbWUsIHNpemU9bWFyaykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNlPVQpICsgCiAgZmFjZXRfd3JhcCh+ZGlzdF90YWlsKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKGkpCgpwcmludChnZykKfQoKYGBgCgojIyMgQ29udHJvbCBmb3Igd2Vla2VuZCBlZmZlY3QgCmBgYHtyfQoKd2Vla2VuZCA8LSBjKDYsIDcsIDEzLCAxNCwgMjAsIDIxKQoKZGZfdXNfbG9lc3MgPC0gZGZfdXMgJT4lIGZpbHRlcighdGltZSAlaW4lIHdlZWtlbmQpICU+JSAKICBzcGxpdCguJGNvdW50eV9maXBzKSAlPiUKICBtYXAofiBsb2Vzcyhzb2NkaXN0X3NpbmdsZV90aWxlIH4gdGltZSwgZGF0YSA9IC4pKSAlPiUKICBtYXAocHJlZGljdCwgMToyMykgJT4lIAogIGJpbmRfcm93cygpICU+JSAKICBnYXRoZXIoa2V5ID0gJ2NvdW50eV9maXBzJywgdmFsdWUgPSAnbG9lc3MnKSAlPiUgCiAgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JSAKICBtdXRhdGUodGltZSA9IHJvd19udW1iZXIoKSkKCmRmX3VzIDwtIGRmX3VzICU+JSBtZXJnZShkZl91c19sb2VzcywgYnk9YygnY291bnR5X2ZpcHMnLCAndGltZScpKSAlPiUgCiAgbXV0YXRlKHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4gPSBpZmVsc2UodGltZSAlaW4lIHdlZWtlbmQsIGxvZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSAlPiUKICBhcnJhbmdlKGNvdW50eV9maXBzLCB0aW1lKQoKZGZfdXMKCmBgYAoKYGBge3J9CgpkZl91cyAlPiUgc2FtcGxlX24oMTAwMDApICU+JQogIGdncGxvdChhZXMoeD10aW1lLCB5PXNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1tYXJrKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZSgiT3ZlcmFsbCBzb2NpYWwgZGlzdGFuY2luZyAoc2luZ2xlIHRpbGUpIG92ZXIgdGltZSIpCgpwZXJzIDwtIGMoJ3BlcnNfbycsICdwZXJzX2MnLCAncGVyc19lJywgJ3BlcnNfYScsICdwZXJzX24nKQoKZm9yIChpIGluIHBlcnMpewoKZ2cgPC0gZGZfdXMgJT4lIG11dGF0ZShkaXN0X3RhaWwgPSBjdXQoLltbaV1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygtSW5mLCBxdWFudGlsZSguW1tpXV0sIDAuMDUpLCBxdWFudGlsZSguW1tpXV0sIDAuOTUpLCBJbmYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdsb3dlciB0YWlsJywgJ2NlbnRlcicsICd1cHBlciB0YWlsJykpKSAlPiUgCiAgZmlsdGVyKGRpc3RfdGFpbCAhPSAnY2VudGVyJykgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPW1hcmspKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIGZhY2V0X3dyYXAofmRpc3RfdGFpbCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZShpKQoKcHJpbnQoZ2cpCn0KCmBgYAoKIyMjIFZhcmlhbmNlIG92ZXIgdGltZQpgYGB7cn0KCmRmX3VzICU+JSBncm91cF9ieSh0aW1lKSAlPiUgCiAgc3VtbWFyaXplKHNvY2Rpc3RfdmFyID0gdmFyKHNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF92YXIpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdndGl0bGUoIlZhcmlhbmNlIG9mIHNvY2lhbCBkaXN0YW5jaW5nIGluZGV4IG92ZXIgdGltZSIpCgoKZGZfdXMgJT4lIGdyb3VwX2J5KHRpbWUpICU+JSAKICBzdW1tYXJpemUoc29jZGlzdF92YXIgPSB2YXIoc29jZGlzdF9zaW5nbGVfdGlsZSksCiAgICAgICAgICAgIHNvY2Rpc3RfdmFyX2NsZWFuID0gdmFyKHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pKSAlPiUgCiAgZ2dwbG90KCkgKwogICNnZW9tX2xpbmUoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3ZhcikpICsKICBnZW9tX2xpbmUoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3Zhcl9jbGVhbikpICsKICBnZ3RpdGxlKCJWYXJpYW5jZSBvZiBzbW90aGVkIHNvY2lhbCBkaXN0YW5jaW5nIGluZGV4IG92ZXIgdGltZSIpCgpgYGAKCgoKCiMjIyBDb3JyZWxhdGlvbnMgCgpgYGB7cn0KCmRmX3VzICU+JSBzZWxlY3QoLXRpbWUsIC1kYXRlLCAtY291bnR5X25hbWUpICU+JSAKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lCiAgc3VtbWFyaXplX2lmKGlzLm51bWVyaWMsIG1lYW4pICU+JSAKICBzZWxlY3QoLWNvdW50eV9maXBzKSAlPiUKICBjb3IodXNlPSdwYWlyd2lzZS5jb21wbGV0ZS5vYnMnKSAlPiUgCiAgcm91bmQoMykKICAKYGBgCgoKIyBNb2RlbCBidWlsZGluZwoKIyMgUHJlcGFyZSBmdW5jdGlvbnMKCmBgYHtyfQoKIyBmdW5jdGlvbiBjYWxjdWxhdGVzIGFsbCByZWxldmFudCBtb2RlbHMKcnVuX21vZGVscyA8LSBmdW5jdGlvbih5LCBsdmwxX3gsIGx2bDJfeCwgbHZsMl9pZCwgZGF0YSwgY3RybHM9Ril7CgogICMgc3Vic2V0IGRhdGEKICBkYXRhID0gZGF0YSAlPiUgCiAgICBkcGx5cjo6c2VsZWN0KGFsbF9vZih5KSwgYWxsX29mKGx2bDFfeCksIGFsbF9vZihsdmwyX3gpLCBhbGxfb2YobHZsMl9pZCksIAogICAgICAgICAgICAgICAgICBwb3BkZW5zLCByYXRlX2RheSwgYWxsX29mKHkpKQogIGRhdGEgPSBkYXRhICU+JSAKICAgIGRwbHlyOjpyZW5hbWUoeSA9IGFsbF9vZih5KSwKICAgICAgICAgICBsdmwxX3ggPSBhbGxfb2YobHZsMV94KSwKICAgICAgICAgICBsdmwyX3ggPSBhbGxfb2YobHZsMl94KSwKICAgICAgICAgICBsdmwyX2lkID0gYWxsX29mKGx2bDJfaWQpCiAgICAgICAgICAgKQogIAogICMgY29uZmlndXJlIG9wdGltaXphdGlvbiBwcm9jZWR1cmUKICBjdHJsX2NvbmZpZyA8LSBsbWVDb250cm9sKG9wdCA9ICdvcHRpbScsIG1heEl0ZXIgPSAxMDAsIG1zTWF4SXRlciA9IDEwMCkKCiAgIyBiYXNlbGluZQogIGJhc2VsaW5lIDwtIGxtZShmaXhlZCA9IHkgfiAxLCByYW5kb20gPSB+IDEgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCgogICMgcmFuZG9tIGludGVyY2VwdCBmaXhlZCBzbG9wZQogIHJhbmRvbV9pbnRlcmNlcHQgPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCArIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiAxIHwgbHZsMl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQoKICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgcmFuZG9tX3Nsb3BlIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKyBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKCiAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogIGludGVyYWN0aW9uIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAjIGNyZWF0ZSBsaXN0IHdpdGggcmVzdWx0cwogIHJlc3VsdHMgPC0gbGlzdCgnYmFzZWxpbmUnID0gYmFzZWxpbmUsIAogICAgICAgICAgICAgICAgICAicmFuZG9tX2ludGVyY2VwdCIgPSByYW5kb21faW50ZXJjZXB0LCAKICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZSIgPSByYW5kb21fc2xvcGUsCiAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbiIgPSBpbnRlcmFjdGlvbikKICAKICAKICBpZiAoY3RybHMgPT0gJ2RlbScgfCBjdHJscyA9PSAncHJldicpewogICAgCiAgICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgICByYW5kb21fc2xvcGVfY3RybF9kZW0gPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCArIGx2bDJfeCArIHBvcGRlbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgICBpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3ggKyBwb3BkZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQogIAogICAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogICAgaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3ggKyBsdmwxX3ggKiBwb3BkZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKSAgICAgICAgCiAgICAKICAgICMgY3JlYXRlIGxpc3Qgd2l0aCByZXN1bHRzCiAgICByZXN1bHRzIDwtIGxpc3QoJ2Jhc2VsaW5lJyA9IGJhc2VsaW5lLCAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX2ludGVyY2VwdCIgPSByYW5kb21faW50ZXJjZXB0LCAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlIiA9IHJhbmRvbV9zbG9wZSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb24iID0gaW50ZXJhY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZV9jdHJsX2RlbSIgPSByYW5kb21fc2xvcGVfY3RybF9kZW0sCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0iID0gaW50ZXJhY3Rpb25fY3RybF9tYWluX2RlbSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtIiA9IGludGVyYWN0aW9uX2N0cmxfaW50X2RlbSkKICB9CiAgCiAgaWYgKGN0cmxzID09ICdwcmV2Jyl7CiAgCiAgICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgICByYW5kb21fc2xvcGVfY3RybF9wcmV2IDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKyBsdmwyX3ggKyBwb3BkZW5zICsgcmF0ZV9kYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94ICsgcmF0ZV9kYXkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykgIAogICAgCiAgICAgICAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogICAgaW50ZXJhY3Rpb25fY3RybF9tYWluX3ByZXYgPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCAqIGx2bDJfeCArIHBvcGRlbnMgKyByYXRlX2RheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAKICAgICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICAgIGludGVyYWN0aW9uX2N0cmxfaW50X3ByZXY8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICogbHZsMl94ICsgbHZsMV94ICogcG9wZGVucyArIHJhdGVfZGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94ICsgcmF0ZV9kYXkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgICAjIGNyZWF0ZSBsaXN0IHdpdGggcmVzdWx0cwogICAgcmVzdWx0cyA8LSBsaXN0KCdiYXNlbGluZScgPSBiYXNlbGluZSwgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9pbnRlcmNlcHQiID0gcmFuZG9tX2ludGVyY2VwdCwgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZSIgPSByYW5kb21fc2xvcGUsCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uIiA9IGludGVyYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGVfY3RybF9kZW0iID0gcmFuZG9tX3Nsb3BlX2N0cmxfZGVtLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtIiA9IGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0sCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfaW50X2RlbSIgPSBpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW0sICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlX2N0cmxfcHJldiIgPSByYW5kb21fc2xvcGVfY3RybF9wcmV2LAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX21haW5fcHJldiIgPSBpbnRlcmFjdGlvbl9jdHJsX21haW5fcHJldiwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldiIgPSBpbnRlcmFjdGlvbl9jdHJsX2ludF9wcmV2KQogIH0KICAKICBpZihjdHJscyA9PSAnZXhwJyl7CiAgICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgcmFuZG9tX3Nsb3BlX2V4cCA8LSBsbWUoZml4ZWQgPSB5IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSArIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IChsdmwxX3ggKyBJKGx2bDFfeF4yKSkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKCiAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogIGludGVyYWN0aW9uX2V4cCA8LSBsbWUoZml4ZWQgPSB5IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSAqIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykgIAogIAogIAogICMgY3JlYXRlIGxpc3Qgd2l0aCByZXN1bHRzCiAgcmVzdWx0cyA8LSBsaXN0KCdiYXNlbGluZScgPSBiYXNlbGluZSwgCiAgICAgICAgICAgICAgICAgICJyYW5kb21faW50ZXJjZXB0IiA9IHJhbmRvbV9pbnRlcmNlcHQsIAogICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlIiA9IHJhbmRvbV9zbG9wZSwKICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uIiA9IGludGVyYWN0aW9uLCAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlX2V4cCIgPSByYW5kb21fc2xvcGVfZXhwLAogICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fZXhwIiA9IGludGVyYWN0aW9uX2V4cCkKICB9CiAgCiAgcmV0dXJuKHJlc3VsdHMpCiAgICAgICAgCn0KCiMgZXh0cmFjdHMgdGFibGUgd2l0aCBjb2VmZmljaWVudHMgYW5kIHRlc3RzIHN0YXRpc3RpY3MKZXh0cmFjdF9yZXN1bHRzIDwtIGZ1bmN0aW9uKG1vZGVscykgewogIAogIG1vZGVsc19zdW1tYXJ5IDwtIG1vZGVscyAlPiUgCiAgbWFwKHN1bW1hcnkpICU+JSAKICBtYXAoInRUYWJsZSIpICU+JSAKICBtYXAoYXMuZGF0YS5mcmFtZSkgJT4lIAogIG1hcChyb3VuZCwgMTApIAogICMgJT4lIG1hcCh+IC5bc3RyX2RldGVjdChyb3duYW1lcyguKSwgJ0ludGVyfGx2bCcpLF0pCiAgCiAgcmV0dXJuKG1vZGVsc19zdW1tYXJ5KQogIAp9CgoKY29tcGFyZV9tb2RlbHMgPC0gZnVuY3Rpb24obW9kZWxzKSB7CgogIG1kbF9uYW1lcyA8LSBtb2RlbHMgJT4lIG5hbWVzKCkKICAKICBzdHIgPSAnJwogIGZvciAoaSBpbiBtZGxfbmFtZXMpewogICAgCiAgICBtZGxfc3RyIDwtIHBhc3RlKCdtb2RlbHMkJywgaSwgc2VwID0gJycpCiAgICAKICAgIGlmKGkgPT0gJ2Jhc2VsaW5lJyl7CiAgICAgIHN0ciA8LSBtZGxfc3RyCiAgICB9ZWxzZXsKICAgIHN0ciA8LSBwYXN0ZShzdHIsIG1kbF9zdHIsIHNlcD0nLCAnKQogICAgfQogIH0KICAKICBhbm92YV9zdHIgPC0gcGFzdGUwKCdhbm92YSgnLCBzdHIsICcpJykKICBtZGxfY29tcCA8LSBldmFsKHBhcnNlKHRleHQ9YW5vdmFfc3RyKSkKICByb3duYW1lcyhtZGxfY29tcCkgPSBtZGxfbmFtZXMKICByZXR1cm4obWRsX2NvbXApCn0KCmBgYAoKIyMgUmVzY2FsZSBEYXRhCmBgYHtyfQoKbHZsMl9zY2FsZWQgPC0gZGZfdXMgJT4lIAogIHNlbGVjdCgtdGltZSwgLW1hcmssIC1kYXRlLCAtY291bnR5X25hbWUsIC1yYXRlX2RheSwKICAgICAgICAgLXNvY2Rpc3RfdGlsZXMsIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbiwgLWxvZXNzKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoLWNvdW50eV9maXBzKSwgc2NhbGUpCgpsdmwxX3NjYWxlZCA8LSBkZl91cyAlPiUgCiAgc2VsZWN0KGNvdW50eV9maXBzLCB0aW1lLCByYXRlX2RheSwgc29jZGlzdF9zaW5nbGVfdGlsZSwgc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikgJT4lIAogIG11dGF0ZV9hdCh2YXJzKC1jb3VudHlfZmlwcywgLXRpbWUpLCBzY2FsZSkKCmRmX3VzX3NjYWxlZCA8LSBwbHlyOjpqb2luKGx2bDFfc2NhbGVkLCBsdmwyX3NjYWxlZCwgYnkgPSAnY291bnR5X2ZpcHMnKQoKZGZfdXNfc2NhbGVkCmBgYAoKCiMjIFByZWRpY3QgcHJldmFsZW5jZQojIyMgcHJldmFsZW5jZSB+IG9wZW5uZXNzCmBgYHtyfQoKbW9kZWxzX29fY292aWQgPC1ydW5fbW9kZWxzKHkgPSAncmF0ZV9kYXknLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfbycsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19vX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX29fY292aWQpCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9Cgptb2RlbHNfY19jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19jX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2NfY292aWQpCgoKYGBgCgojIyMgcHJldmFsZW5jZSB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCm1vZGVsc19lX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2VfY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfZV9jb3ZpZCkKCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCm1vZGVsc19hX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfYScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2FfY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfYV9jb3ZpZCkKCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gbmV1cm90aWNpc20KYGBge3J9Cgptb2RlbHNfbl9jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19uX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX25fY292aWQpCgoKYGBgCgoKIyMgUHJlZGljdCBzb2NpYWwgZGlzdGFuY2luZwojIyMgc29jaWFsIGRpc3RhbmNpbmcgfiBvcGVubmVzcwpgYGB7cn0KCm1vZGVsc19vX3NkIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19vJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAncHJldicpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX29fc2QpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfb19zZCkKCgpgYGAKCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKbW9kZWxzX2Nfc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfY19zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19jX3NkKQoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKbW9kZWxzX2Vfc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2UnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfZV9zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19lX3NkKQoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCm1vZGVsc19hX3NkIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19hJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAncHJldicpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2Ffc2QpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfYV9zZCkKCgpgYGAKCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IG5ldXJvdGljaXNtCmBgYHtyfQoKbW9kZWxzX25fc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfbl9zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19uX3NkKQoKYGBgCgoKIyMgQ3JlYXRlIG92ZXJ2aWV3IHRhYmxlIAoKIyMjIERlZmluZSBmdW5jdGlvbiB0byBjcmVhdGUgb3ZlcnZpZXcgdGFibGVzCmBgYHtyfQoKc3VtbWFyeV90YWJsZSA8LSBmdW5jdGlvbihtb2RlbHMsIGR2X25hbWUsIHByZXY9Ril7CgogIHRlbXBfZGZfY3RybF9tYWluIDwtIE5VTEwKICB0ZW1wX2RmX2N0cmxfaW50IDwtIE5VTEwKICB0ZW1wX2RmX2N0cmxfaW50X3ByZXYgPC0gTlVMTAogIAogIGZvciAoaSBpbiBtb2RlbHMpewogICAgcmVzdWx0cyA8LSBpICU+JSBleHRyYWN0X3Jlc3VsdHMoKQogICAgCiAgICByZXN1bHRzX2N0cmxfbWFpbiA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW1bJ2x2bDFfeDpsdmwyX3gnLF0KICAgIHRlbXBfZGZfY3RybF9tYWluIDwtIHRlbXBfZGZfY3RybF9tYWluICU+JSByYmluZChyZXN1bHRzX2N0cmxfbWFpbikKICAgIAogICAgcmVzdWx0c19jdHJsX2ludCA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfaW50X2RlbVsnbHZsMV94Omx2bDJfeCcsXQogICAgdGVtcF9kZl9jdHJsX2ludCA8LSB0ZW1wX2RmX2N0cmxfaW50ICU+JSByYmluZChyZXN1bHRzX2N0cmxfaW50KQogICAgCiAgICBpZihwcmV2KXsKICAgICAgcmVzdWx0c19jdHJsX2ludF9wcmV2IDwtIHJlc3VsdHMkaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldlsnbHZsMV94Omx2bDJfeCcsXQogICAgICB0ZW1wX2RmX2N0cmxfaW50X3ByZXYgPC0gdGVtcF9kZl9jdHJsX2ludF9wcmV2ICU+JSByYmluZChyZXN1bHRzX2N0cmxfaW50X3ByZXYpCiAgICB9CiAgICAgICAgCiAgfQogIAogIG5hbWVzX2N0cmxfbWFpbiA8LSBwYXN0ZTAoZHZfbmFtZSwgJ34nLCBjKCdvJywgJ2MnLCAnZScsICdhJywgJ24nKSwgJyp0aW1lJywgJ19jcnRsX3BvcGRlbnMnKQogIHJvd25hbWVzKHRlbXBfZGZfY3RybF9tYWluKSA8LSBuYW1lc19jdHJsX21haW4KCiAgbmFtZXNfY3RybF9pbnQgPC0gcGFzdGUwKGR2X25hbWUsICd+JywgYygnbycsICdjJywgJ2UnLCAnYScsICduJyksICcqdGltZScsICdfY3J0bF9wb3BkZW5zKnRpbWUnKQogIHJvd25hbWVzKHRlbXBfZGZfY3RybF9pbnQpIDwtIG5hbWVzX2N0cmxfaW50CgogIGlmKHByZXYpewogICAgbmFtZXNfY3RybF9pbnRfcHJldiA8LSBwYXN0ZTAoZHZfbmFtZSwgJ34nLCBjKCdvJywgJ2MnLCAnZScsICdhJywgJ24nKSwgJyp0aW1lJywgJ19jcnRsX3BvcGRlbnMqdGltZV9wcmV2JykKICAgIHJvd25hbWVzKHRlbXBfZGZfY3RybF9pbnRfcHJldikgPC0gbmFtZXNfY3RybF9pbnRfcHJldgogICAgCiAgICBzdW1fdGFiIDwtIHJiaW5kKHRlbXBfZGZfY3RybF9tYWluLCB0ZW1wX2RmX2N0cmxfaW50LCB0ZW1wX2RmX2N0cmxfaW50X3ByZXYpICU+JSByb3VuZCg0KQogIH1lbHNlewogICAgc3VtX3RhYiA8LSByYmluZCh0ZW1wX2RmX2N0cmxfbWFpbiwgdGVtcF9kZl9jdHJsX2ludCkgJT4lIHJvdW5kKDQpCiAgfQoKCiAgCiAgcmV0dXJuKHN1bV90YWIpCgp9IAoKYGBgCgojIyMgQ3JlYXRlIG92ZXJ2aWV3IHRhYmxlcwpgYGB7cn0KIyBwcmV2YWxlbmNlCm1vZGVsc19wcmV2IDwtIGxpc3QobW9kZWxzX29fY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX2NvdmlkLCAKICAgICAgICAgICAgICAgICAgICBtb2RlbHNfZV9jb3ZpZCwgCiAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2FfY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX2NvdmlkKQoKc3VtX3RhYl9wcmV2IDwtIHN1bW1hcnlfdGFibGUobW9kZWxzX3ByZXYsIGR2X25hbWUgPSAncHJldicpCgp3cml0ZS50YWJsZShzdW1fdGFiX3ByZXYsIHF1b3RlPUYpCgojIHNvY2lhbCBkaXN0YW5jaW5nCm1vZGVsc19zb2NkaXN0IDwtIGxpc3QobW9kZWxzX29fc2QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX3NkLCAKICAgICAgICAgICAgICAgICAgICAgICBtb2RlbHNfZV9zZCwgCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2Ffc2QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX3NkKQoKc3VtX3RhYl9zb2NkaXN0IDwtIHN1bW1hcnlfdGFibGUobW9kZWxzX3NvY2Rpc3QsIGR2X25hbWUgPSAnc29jZGlzdCcsIHByZXY9VCkKCndyaXRlLnRhYmxlKHN1bV90YWJfc29jZGlzdCwgcXVvdGU9RikKCgpgYGAKCgoKCiMgQ29uZGl0aW9uYWwgcmFuZG9tIGZvcmVzdCBhbmFseXNpcyAKCiMjIyBFeHRyYWN0IHNsb3BlcwpgYGB7cn0KCiMgc2xvcGUgcHJldmFsZW5jZQpkZl91c19zbG9wZV9wcmV2IDwtIGRmX3VzX3NjYWxlZCAlPiUgc3BsaXQoLiRjb3VudHkpICU+JSAKICBtYXAofiBsbShyYXRlX2RheSB+IHRpbWUsIGRhdGEgPSAuKSkgJT4lCiAgbWFwKGNvZWYpICU+JSAKICBtYXBfZGJsKCd0aW1lJykgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpICU+JSAKICByZW5hbWUoc2xvcGVfcHJldiA9ICcuJykKCmRmX3VzX3Nsb3BlX3ByZXYgPC0gZGZfdXNfc2NhbGVkICU+JSBzZWxlY3QoLXRpbWUsIC1yYXRlX2RheSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZShjb3VudHlfZmlwcyA9IGFzLmNoYXJhY3Rlcihjb3VudHlfZmlwcykpICU+JQogIGlubmVyX2pvaW4oZGZfdXNfc2xvcGVfcHJldiwgYnkgPSAnY291bnR5X2ZpcHMnKSAlPiUKICBkcm9wX25hKCkKCgoKIyBzbG9wZSBzb2NpYWwgZGlzdGFuY2luZwpkZl91c19zbG9wZV9zb2NkaXN0IDwtIGRmX3VzX3NjYWxlZCAlPiUgc3BsaXQoLiRjb3VudHkpICU+JSAKICBtYXAofiBsbShzb2NkaXN0X3NpbmdsZV90aWxlIH4gdGltZSwgZGF0YSA9IC4pKSAlPiUKICBtYXAoY29lZikgJT4lIAogIG1hcF9kYmwoJ3RpbWUnKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykgJT4lIAogIHJlbmFtZShzbG9wZV9zb2NkaXN0ID0gJy4nKQoKZGZfdXNfc2xvcGVfc29jZGlzdCA8LSBkZl91c19zY2FsZWQgJT4lIHNlbGVjdCgtdGltZSwgLXJhdGVfZGF5LCAtc29jZGlzdF9zaW5nbGVfdGlsZSkgJT4lCiAgZGlzdGluY3QoKSAlPiUgCiAgbXV0YXRlKGNvdW50eV9maXBzID0gYXMuY2hhcmFjdGVyKGNvdW50eV9maXBzKSkgJT4lCiAgaW5uZXJfam9pbihkZl91c19zbG9wZV9zb2NkaXN0LCBieSA9ICdjb3VudHlfZmlwcycpICU+JQogIGRyb3BfbmEoKQoKZGZfdXNfc2xvcGVfc29jZGlzdApgYGAKCiMjIyBFeHBsb3JlIGRpc3RyaWJ1dGlvbiBvZiBzbG9wZXMKYGBge3J9CmRmX3VzX3Nsb3BlX3ByZXYgJT4lIGdncGxvdChhZXMoc2xvcGVfcHJldikpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCkKCmRmX3VzX3Nsb3BlX3NvY2Rpc3QgJT4lIGdncGxvdChhZXMoc2xvcGVfc29jZGlzdCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCkKCmBgYAoKIyBDUkYgcHJldmFsZW5jZSB+IG9wZW5uZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9vX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfbyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfb192YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX29fZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX29fdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX29fZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX29fdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX29fdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgcHJldmFsZW5jZSB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9jX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfYyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfY192YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2NfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBwcmV2YWxlbmNlIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9lX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfZSArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfZV92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2VfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2VfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2VfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2VfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2VfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBwcmV2YWxlbmNlIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfYV9maXRfcHJldiA8LSBjZm9yZXN0KHNsb3BlX3ByZXYgfiBwZXJzX2EgKyBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl91c19zbG9wZV9wcmV2Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2FfdmFyaW1wX3ByZXYgPC0gdmFyaW1wKGNyZl9hX2ZpdF9wcmV2LCBucGVybSA9IDEpCmNyZl9hX3ZhcmltcF9jb25kX3ByZXYgPC0gdmFyaW1wKGNyZl9hX2ZpdF9wcmV2LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9hX3ZhcmltcF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9hX3ZhcmltcF9jb25kX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgoKIyBDUkYgcHJldmFsZW5jZSB+IG5ldXJvdGljaXNtCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9uX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfbiArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IG9wZW5uZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9vX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfbyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfb192YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX29fZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX29fdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX29fZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX29fdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX29fdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMgQ1JGIHNvY2lhbCBkaXN0YW5jaW5nIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2NfZml0X3NvY2Rpc3QgPC0gY2ZvcmVzdChzbG9wZV9zb2NkaXN0IH4gcGVyc19jICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9jX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfY19maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfY192YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfY19maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfY192YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfY192YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBleHRyYXZlcnNpb24KYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2VfZml0X3NvY2Rpc3QgPC0gY2ZvcmVzdChzbG9wZV9zb2NkaXN0IH4gcGVyc19lICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9lX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfZV9maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfZV92YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfZV9maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfZV92YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfZV92YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9hX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfYSArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfYV92YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX2FfZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX2FfdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX2FfZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2FfdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2FfdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IG5ldXJvdGljaXNtCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9uX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfbiArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX25fZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX25fZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMgTGluZWFyIG1vZGVscyBwcmVkaWN0aW5nIHNsb3BlcyBmcm9tIHBlcnNvbmFsaXR5CmBgYHtyfQoKbG1fc2xvcGVfcHJldl9wZXJzIDwtIGxtKHNsb3BlX3ByZXYgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3Nsb3BlX3ByZXYpCmxtX3Nsb3BlX3ByZXZfcGVycyAlPiUgc3VtbWFyeSgpCgoKbG1fc2xvcGVfc29jZGlzdF9wZXJzIDwtIGxtKHNsb3BlX3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3Nsb3BlX3NvY2Rpc3QpCmxtX3Nsb3BlX3NvY2Rpc3RfcGVycyAlPiUgc3VtbWFyeSgpCgpgYGAKCiMgTGluZWFyIG1vZGVscyBwcmVkaWN0aW5nIHNsb3BlcyB3aXRoIGNvbnRyb2xzCmBgYHtyfQoKbG1fc2xvcGVfcHJldl9wZXJzIDwtIGxtKHNsb3BlX3ByZXYgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24gKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKyBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYW51ZmFjdCArIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2xvcGVfcHJldikKbG1fc2xvcGVfcHJldl9wZXJzICU+JSBzdW1tYXJ5KCkKCgpsbV9zbG9wZV9zb2NkaXN0X3BlcnMgPC0gbG0oc2xvcGVfc29jZGlzdCB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbnVmYWN0ICsgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zbG9wZV9zb2NkaXN0KQpsbV9zbG9wZV9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgoKYGBge3J9CmxpYnJhcnkodGlncmlzKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCgptZSA8LSBjb3VudGllcyhjYiA9IFRSVUUpCm1lX21hcCA8LSBmb3J0aWZ5KG1lKQpwbG90KG1lX21hcCkKCm1lX21hcCAlPiUgaGVhZCgpCm1lICU+JSBoZWFkKCkKCmdnIDwtIGdncGxvdCgpCmdnIDwtIGdnICsgZ2VvbV9tYXAoZGF0YT11c19tYXBfc2hhcGUsIG1hcD11c19tYXBfc2hhcGUsCiAgICAgICAgICAgICAgICAgICAgYWVzKCB4ID0geCwgeSA9IHksIG1hcF9pZD1maXBzKSwKICAgICAgICAgICAgICAgICAgICBjb2xvcj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIsIHNpemU9MC4yNSkKZ2cgPC0gZ2cgKyBjb29yZF9tYXAoKQpnZyA8LSBnZyArIHRoZW1lX21hcCgpCmdnCmBgYAoKYGBge3J9CmRmX3VzX2NvdmlkICU+JSBmaWx0ZXIoY291bnR5ID09IDIzMDEzKQoKYGBgCgoKYGBge3J9CgpsaWJyYXJ5KHVzbWFwKQpsaWJyYXJ5KGdncGxvdDIpCgp1c19tYXBfc2hhcGUgPSB1c19tYXAocmVnaW9ucyA9ICdjb3VudGllcycpCgp1c19tYXBfc2hhcGUKCnBsb3RfdXNtYXAoZGF0YSA9IHVzX21hcF9zaGFwZSkgKyAKICBsYWJzKHRpdGxlID0gIlVTIENvdW50aWVzIiwKICAgICAgIHN1YnRpdGxlID0gIlRoaXMgaXMgYSBibGFuayBtYXAgb2YgdGhlIGNvdW50aWVzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiIpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSAibGlnaHRibHVlIikpCmBgYAoKIyBDaGFuZ2UgcG9pbnQgYW5hbHlzaXMKCmBgYHtyfQpsaWJyYXJ5KGNoYW5nZXBvaW50KQpgYGAKCiMjIyBQcmVwYXJhdGlvbgpgYGB7cn0KIyBrZWVwIG9ubHkgY291bnRpZXMgd2l0aCBmdWxsIGRhdGEKZmlwc19jb21wbGV0ZSA8LSBkZl91c19zY2FsZWQgJT4lIAogIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXplKG4gPSBuKCkpICU+JSAKICBmaWx0ZXIobj09bWF4KC4kbikpICU+JSAKICAuJGNvdW50eV9maXBzCmBgYAoKCmBgYHtyfQpkZl91c19zY2FsZWQKYGBgCgoKIyMjIFByZXZhbGVuY2UKYGBge3J9CgojIHJ1biBjaGFuZ2Vwb2ludCBhbmFseXNpcwpkZl91c19wcmV2X2NwdF9yZXN1bHRzIDwtIGRmX3VzX3NjYWxlZCAlPiUgc2VsZWN0KGNvdW50eV9maXBzLCByYXRlX2RheSkgJT4lCiAgZmlsdGVyKGNvdW50eV9maXBzICVpbiUgZmlwc19jb21wbGV0ZSkgJT4lIAogIHNwbGl0KC4kY291bnR5X2ZpcHMpICU+JQogIG1hcCh+IGNwdC5tZWFudmFyKGFzLnZlY3RvciguJHJhdGVfZGF5KSwKICAgICAgICAgICAgICAgICAgICBjbGFzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIHBhcmFtLmVzdGltYXRlcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIFE9MSkpCgojIGNhbGN1bGF0ZSBjaGFuZ2UgcG9pbnQKZGZfdXNfcHJldl9jcHRfZGF5IDwtIGRmX3VzX3ByZXZfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChjcHRzKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKGNwdF9kYXlfcHJldiA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpCgojIGNhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCmRmX3VzX3ByZXZfY3B0X21lYW5fZGlmZiA8LSBkZl91c19wcmV2X2NwdF9yZXN1bHRzICU+JSAKICBtYXAocGFyYW0uZXN0KSAlPiUgCiAgbWFwKH4gLiRtZWFuKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKG1lYW5fZGlmZl9wcmV2ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykKCiMgY2FsY3VsYXRlIHZhcmFpbmNlIGRpZmZlcmVuY2VzCmRmX3VzX3ByZXZfY3B0X3Zhcl9kaWZmIDwtIGRmX3VzX3ByZXZfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJHZhcmlhbmNlKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKHZhcl9kaWZmX3ByZXYgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbignY291bnR5X2ZpcHMnKQoKIyBtZXJnZSBuZXcgdmFyaWFibGVzIApkZl91c19jcHRfcHJldiA8LSBkZl91c19zY2FsZWQgJT4lCiAgc2VsZWN0KC10aW1lLCAtcmF0ZV9kYXksIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBtdXRhdGUoY291bnR5X2ZpcHMgPSBhcy5jaGFyYWN0ZXIoY291bnR5X2ZpcHMpKSAlPiUKICBsZWZ0X2pvaW4oZGZfdXNfcHJldl9jcHRfZGF5LCBieT0nY291bnR5X2ZpcHMnKSAlPiUKICBsZWZ0X2pvaW4oZGZfdXNfcHJldl9jcHRfbWVhbl9kaWZmLCBieT0nY291bnR5X2ZpcHMnKSAlPiUKICBsZWZ0X2pvaW4oZGZfdXNfcHJldl9jcHRfdmFyX2RpZmYsIGJ5PSdjb3VudHlfZmlwcycpCgpkZl91c19jcHRfcHJldiAlPiUgc2VsZWN0KGNwdF9kYXlfcHJldikgJT4lIG1hcChoaXN0KQpkZl91c19jcHRfcHJldiAlPiUgc2VsZWN0KG1lYW5fZGlmZl9wcmV2KSAlPiUgbWFwKGhpc3QpCmRmX3VzX2NwdF9wcmV2ICU+JSBzZWxlY3QodmFyX2RpZmZfcHJldikgJT4lIG1hcChoaXN0KQoKZGZfdXNfY3B0X3ByZXYgJT4lIGRpbSgpCmRmX3VzX2NwdF9wcmV2ICU+JSBkcm9wX25hKCkgJT4lIGRpbSgpCgpgYGAKCgpgYGB7cn0KCmZvcihpIGluIGhlYWQoZGZfdXNfcHJldl9jcHRfcmVzdWx0cywxOCkpewogIHBsb3QoaSkKfQoKYGBgCgojIyMgU29jZGlzdApgYGB7cn0KCiMgcnVuIGNoYW5nZXBvaW50IGFuYWx5c2lzCmRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgPC0gZGZfdXNfc2NhbGVkICU+JSBzZWxlY3QoY291bnR5X2ZpcHMsIHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pICU+JQogIGZpbHRlcihjb3VudHlfZmlwcyAlaW4lIGZpcHNfY29tcGxldGUpICU+JSAKICBzcGxpdCguJGNvdW50eV9maXBzKSAlPiUKICBtYXAofiBjcHQubWVhbnZhcihhcy52ZWN0b3IoLiRzb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuKSwKICAgICAgICAgICAgICAgICAgICAjcGVuYWx0eSA9ICdBc3ltcHRvdGljJywKICAgICAgICAgICAgICAgICAgICBjbGFzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIHBhcmFtLmVzdGltYXRlcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIFE9MSwKICAgICAgICAgICAgICAgICAgICB0ZXN0LnN0YXQgPSAnTm9ybWFsJykpCgojIGNhbGN1bGF0ZSBjaGFuZ2UgcG9pbnQKZGZfdXNfc29jZGlzdF9jcHRfZGF5IDwtIGRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChjcHRzKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKGNwdF9kYXlfc29jZGlzdCA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpCgojIGNhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCmRmX3VzX3NvY2Rpc3RfY3B0X21lYW5fZGlmZiA8LSBkZl91c19zb2NkaXN0X2NwdF9yZXN1bHRzICU+JSAKICBtYXAocGFyYW0uZXN0KSAlPiUgCiAgbWFwKH4gLiRtZWFuKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKG1lYW5fZGlmZl9zb2NkaXN0ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykKCiMgY2FsY3VsYXRlIHZhcmFpbmNlIGRpZmZlcmVuY2VzCmRmX3VzX3NvY2Rpc3RfY3B0X3Zhcl9kaWZmIDwtIGRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJHZhcmlhbmNlKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKHZhcl9kaWZmX3NvY2Rpc3QgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbignY291bnR5X2ZpcHMnKQoKIyBtZXJnZSBuZXcgdmFyaWFibGVzIApkZl91c19jcHRfcHJldl9zb2NkaXN0IDwtIGRmX3VzX2NwdF9wcmV2ICU+JQogIGxlZnRfam9pbihkZl91c19zb2NkaXN0X2NwdF9kYXksIGJ5PSdjb3VudHlfZmlwcycpICU+JQogIGxlZnRfam9pbihkZl91c19zb2NkaXN0X2NwdF9tZWFuX2RpZmYsIGJ5PSdjb3VudHlfZmlwcycpICU+JQogIGxlZnRfam9pbihkZl91c19zb2NkaXN0X2NwdF92YXJfZGlmZiwgYnk9J2NvdW50eV9maXBzJykKCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIHNlbGVjdChjcHRfZGF5X3NvY2Rpc3QpICU+JSBtYXAoaGlzdCkKZGZfdXNfY3B0X3ByZXZfc29jZGlzdCAlPiUgc2VsZWN0KG1lYW5fZGlmZl9zb2NkaXN0KSAlPiUgbWFwKGhpc3QpCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIHNlbGVjdCh2YXJfZGlmZl9zb2NkaXN0KSAlPiUgbWFwKGhpc3QpCgpkZl91c19jcHRfcHJldl9zb2NkaXN0ICU+JSBkaW0oKQpkZl91c19jcHRfcHJldl9zb2NkaXN0ICU+JSBkcm9wX25hKCkgJT4lIGRpbSgpCgpgYGAKCmBgYHtyfQoKZm9yKGkgaW4gaGVhZChkZl91c19zb2NkaXN0X2NwdF9yZXN1bHRzLDE4KSl7CiAgcGxvdChpKQp9CgpgYGAKYGBge3J9CmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QKYGBgCgojIFByZWRpY3RpbmcgY2hhbmdlIHBvaW50cyAKIyMjIExpbmVhciBtb2RlbHMgcHJlZGljdGluZyBjaGFuZ2UgcG9pbnRzIChubyBjb250cm9scykKYGBge3J9CgpsbV9jcHJfcHJldl9wZXJzIDwtIGxtKGNwdF9kYXlfcHJldiB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfY3B0X3ByZXZfc29jZGlzdCkKbG1fY3ByX3ByZXZfcGVycyAlPiUgc3VtbWFyeSgpCgoKbG1fY3B0X3NvY2Rpc3RfcGVycyA8LSBsbShjcHRfZGF5X3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgojIExpbmVhciBtb2RlbHMgcHJlZGljdGluZyBjaGFuZ2UgcG9pbnRzIHdpdGggY29udHJvbHMKYGBge3J9CgpsbV9jcHRfcHJldl9wZXJzIDwtIGxtKGNwdF9kYXlfcHJldiB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiArIAogICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbnVmYWN0ICsgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19jcHRfcHJldl9zb2NkaXN0KQpsbV9jcHRfcHJldl9wZXJzICU+JSBzdW1tYXJ5KCkKCmxtX2NwdF9zb2NkaXN0X3BlcnMgPC0gbG0oY3B0X2RheV9zb2NkaXN0IH4gcGVyc19vICsgcGVyc19jICsgcGVyc19lICsgcGVyc19hICsgcGVyc19uICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFudWZhY3QgKyB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgoK
Social distancing data unacast